package fm.douban;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.PlayerListener;
import javax.microedition.media.control.VolumeControl;

import net.rim.device.api.i18n.ResourceBundle;
import net.rim.device.api.math.Fixed32;
import net.rim.device.api.media.MediaActionHandler;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Keypad;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.PopupScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.decor.Background;
import net.rim.device.api.ui.decor.BackgroundFactory;

import org.json.me.JSONArray;
import org.json.me.JSONException;
import org.json.me.JSONObject;
import org.json.me.JSONTokener;

public class SongPlayScreen extends MainScreen {
	public static ResourceBundle _resources = ResourceBundle.getBundle(
			RadioResource.BUNDLE_ID, RadioResource.BUNDLE_NAME);
	public String _url = "";

	public HttpConnection _httpConnection;

	public JSONArray songs;

	public InputStream is;

	public String s_pic;

	public String s_url;

	public String s_title;

	public String s_artist;

	public String s_id = "";

	public EncodedImage bitmap;

	public BitmapField bitField;

	public LabelField artistField;

	/** A player for the media stream. */
	private Player _player;

	/** A stream for the resource we are retrieving */
	private LimitedRateStreamingSource _source;

	/** A thread which creates and starts the Player */
	private PlayerThread _playerThread;

	private Random _random = new Random();

	private long autoCloseTime;

	private String[] _history = new String[] { "190052:p", "192381:p",
			"758929:p", "184020:p", "66948:p", "759115:p", "33202:p",
			"1383197:p", "641434:p", "179375:p", "186110:p", "1383257:p",
			"742971:p", "1381262:p", "675142:p", "12226:p", "753557:p",
			"352458:p", "643236:p", "339555:p" };

	/** A field used to display the number of bytes that have been loaded */
	// private BasicEditField _loadStatusField;
	int amount = 0;

	public int s_idx = 0;

	private JSONObject s;

	private VolumeControl vc;

	private LabelField f_time;

	private int channel = Integer.parseInt(LoginUtil.CHANNEL);

	private int _volume = 50;

	private boolean _timeStop;
	private int initalTitle;
	private MenuItem _switchChannel = new MyMenuItem(_resources,
			RadioResource.SWITCH_CHANNEL, 1, 2, Channel.BEATLES_CHINESE);
	private MenuItem next = new MenuItem(_resources, RadioResource.NEXT, 1, 2) {
		public void run() {
			channelSwitch(100);
		}
	};

	private MenuItem rate = new MenuItem(_resources, RadioResource.RATE, 1, 2) {
		public void run() {
			Thread t = new Thread(new Runnable() {
				public void run() {
					processEndStatus("r");
				}
			});
			t.start();
		}
	};
	private MenuItem delete = new MenuItem(_resources,
			RadioResource.NEVER_PLAY_AGAIN, 1, 2) {
		public void run() {
			Thread t = new Thread(new Runnable() {
				public void run() {
					processEndStatus("b");
				}
			});
			t.start();
		}
	};
	private MenuItem clearLogin = new MenuItem(_resources,
			RadioResource.REMOVE_LOGIN, 1, 2) {
		public void run() {
			LoginUtil.deleteDB();
		}
	};
	private boolean aCChecked = false;
	private Timer aCTimer = new Timer();

	private class aCTask extends TimerTask {
		public void run() {
			if (aCChecked)
				close();
		}
	}

	private aCTask task = new aCTask();
	private MenuItem setAutoClose = new MenuItem(_resources,
			RadioResource.AUTO_CLOSE_MENU_ITEM, 1, 2) {
		private String menuText = this.getBundle().getString(this.getId());

		public void run() {
			if (!aCChecked) {
				this.setText(Characters.BALLOT_BOX_WITH_CHECK + menuText);
				aCTimer.schedule(task, 60 * 30 * 1000l);
			} else {
				this.setText(menuText);
				task.cancel();
			}

		}
	};
	private AboutDialog ad = new AboutDialog();
	private MenuItem about = new MenuItem(_resources, RadioResource.ABOUT, 1, 2) {
		public void run() {
			Radio theApp = (Radio) getApplication();
			theApp.pushGlobalScreen(ad, 1, UiApplication.GLOBAL_MODAL);
		}
	};

	private static class AboutDialog extends PopupScreen {
		private LabelField appName = new LabelField(
				_resources.getString(RadioResource.VERSION),
				Field.FIELD_HCENTER);
		private LabelField author_email = new LabelField(
				_resources.getString(RadioResource.AUTH_EMAIL),
				Field.FIELD_HCENTER);
		private LabelField author_blog = new LabelField(
				_resources.getString(RadioResource.AUTH_BLOG),
				Field.FIELD_HCENTER);
		private ButtonField btnOk = new ButtonField("OK", Field.FIELD_HCENTER);

		private FieldChangeListener ok = new FieldChangeListener() {
			public void fieldChanged(Field field, int context) {
				getScreen().close();
			}
		};
		private static VerticalFieldManager v = new VerticalFieldManager();

		public AboutDialog() {
			super(v);
			v.add(appName);
			// v.add(author_email);
			v.add(author_blog);
			btnOk.setChangeListener(ok);
			v.add(btnOk);
		}

	}

	private LabelField titleLabel;

	private Random rand = new Random();

	private boolean _changeChannel = false;

	public SongPlayScreen() {

		new Thread(new Runnable() {
			public void run() {
				init();
			}
		}).start();
		try {
			initScreen();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void initScreen() throws IOException {
		// s_pic = "http://img3.douban.com/pics/nav/lg_main_a6.png";
		// fetchImage(s_pic);
		initalTitle = getTitle();
		titleLabel = new LabelField(_resources.getString(initalTitle));
		bitmap = EncodedImage.getEncodedImageResource("fm.png");// Bitmap.getBitmapResource("fm.png").;
		// bitmap = bitmap.scaleImage32(Fixed32.HALF, Fixed32.HALF);
		bitField = new BitmapField(bitmap.getBitmap(), FIELD_HCENTER
				| FIELD_VCENTER);

		bitField.setMargin(10, 0, 0, 0);
		add(bitField);

		f_time = new LabelField("", FIELD_HCENTER);
		f_time.setMargin(10, 0, 0, 0);
		add(f_time);

		artistField = new LabelField("", Field.FIELD_HCENTER);
		artistField.setMargin(10, 0, 0, 0);
		add(artistField);

		Background background = BackgroundFactory
				.createSolidTransparentBackground(Color.GRAY, 80);
		getMainManager().setBackground(background);
		processMenuItem();
		processMediaKey();
	}

	private int getTitle() {
		switch (Integer.parseInt(LoginUtil.CHANNEL)) {
		case Channel.BALLAD:
			return RadioResource.BALLAD;
		case Channel.BEATLES_CHINESE:
			return RadioResource.BEATLES_CHINESE;
		case Channel.CANTONESE:
			return RadioResource.CANTONESE;
		case Channel.EIGHTIES:
			return RadioResource.EIGHTIES;
		case Channel.EUROPEAN:
			return RadioResource.EUROPEAN;
		case Channel.LIGHT_MUSIC:
			return RadioResource.LIGHT_MUSIC;
		case Channel.MOVIE_ORIGINAL:
			return RadioResource.MOVIE_ORIGINAL;
		case Channel.NINETIES:
			return RadioResource.NINETIES;
		case Channel.ROCK:
			return RadioResource.ROCK;
		case Channel.SEVENTIES:
			return RadioResource.SEVENTIES;
		case Channel.JAZZ:
			return RadioResource.JAZZ;
		case Channel.RAP:
			return RadioResource.RAP;
		case Channel.RB:
			return RadioResource.RB;
		case Channel.JAPANESE:
			return RadioResource.JAPANESE;
		case Channel.KOREAN:
			return RadioResource.KOREAN;
		case Channel.PUMA:
			return RadioResource.PUMA;
		case Channel.ELECTRONIC:
			return RadioResource.ELECTRONIC;
		case Channel.GIRLS:
			return RadioResource.GIRLS;
		case Channel.OMP:
			return RadioResource.OMP;
		case Channel.FRENCH:
			return RadioResource.FRENCH;
		case Channel.GEGE:
			return RadioResource.GEGE;
		default:
			return RadioResource.PERSONAL;
		}
	}

	private void processMediaKey() {
		//Radio theApp = (Radio) getApplication();
		Radio.theApp.addMediaActionHandler(new MyMediaActionHandler());
	}

	public class MyMediaActionHandler implements MediaActionHandler {
		public boolean mediaAction(int action, int source, Object context) {
			System.out.println("action:" + action);

			VolumeControl v = (VolumeControl) _player
					.getControl("VolumeControl");
			if (action == MediaActionHandler.MEDIA_ACTION_VOLUME_DOWN) {
				v.setLevel(v.getLevel() - 10);
				_volume = vc.getLevel();
			} else if (action == MediaActionHandler.MEDIA_ACTION_VOLUME_UP) {
				v.setLevel(v.getLevel() + 10);
				_volume = vc.getLevel();
			} else if (action == MediaActionHandler.MEDIA_ACTION_MUTE
					|| action == MediaActionHandler.MEDIA_ACTION_PLAYPAUSE_TOGGLE) {
				if (!v.isMuted())
					v.setMute(true);
				else
					v.setMute(false);
			} else if (action == MediaActionHandler.MEDIA_ACTION_UNMUTE) {
				if (v.isMuted())
					v.setMute(false);
				else
					v.setMute(true);
			} else if (action == MediaActionHandler.MEDIA_ACTION_PAUSE) {
				System.out
						.println("action:MediaActionHandler.MEDIA_ACTION_PAUSE");
			} else if (action == MediaActionHandler.MEDIA_ACTION_STOP) {
				System.out
						.println("action:MediaActionHandler.MEDIA_ACTION_PAUSE");
			} else if (action == MediaActionHandler.MEDIA_ACTION_NEXT_TRACK) { //
				channelSwitch(100);
			}
			return false;
		}
	}

	public void init() {
		try {
			int i = 0;
			while (songs == null && !_retrieveSongsSusccess) {
				synchronized (UiApplication.getEventLock()) {
					setTitle("connecting....." + i);
					updateLayout();
				}
				i++;
				prepData();
				if (_retrieveSongsSusccess)
					break;
				Thread.sleep(5000l);
				if (i == 5) {
					throw new MyException("retried 5 times.");
				}
			}
			amount = songs.length();
			synchronized (UiApplication.getEventLock()) {
				prepScreen();
				updateLayout();
			}
		} catch (IOException e) {
			System.out.println("in constructor:" + e.getClass());
			System.out.println("in constructor:" + e.getMessage());
			Radio.errorDialog(SongPlayScreen._resources
					.getString(RadioResource.IO_ERROR));
		} catch (JSONException e) {
			System.out.println("in constructor:" + e.getClass());
			System.out.println("in constructor:" + e.getMessage());
			Radio.errorDialog("in constructor:" + e.getClass() + ":"
					+ e.getMessage());
		} catch (MyException e) {
			System.out.println("in constructor:" + e.getClass());
			System.out.println("in constructor:" + e.getMessage());
			Radio.errorDialog("in constructor:" + e.getClass() + ":"
					+ e.getMessage());
		} catch (InterruptedException e) {
			System.out.println("in constructor:" + e.getClass());
			System.out.println("in constructor:" + e.getMessage());
			Radio.errorDialog("in constructor:" + e.getClass() + ":"
					+ e.getMessage());
		}

	}

	public static class MyException extends Exception {
		public MyException(String msg) {
			super(msg);
		}
	}

	private void wrapURL() {
		_url = _resources.getString(RadioResource.URL_BASE);// +
		_url += "r=" + _random.nextDouble();
		_url += "&type=n&sid=" + s_id;
		_url += "&uid=" + LoginUtil.UID;
//		if (_history != null && !_history.equals(""))
//			_url += "&h=" + toStr(_history);
		_url += "&du=0&channel=" + channel;
		System.out.println(_url);
	}

	public String toStr(String[] his) {
		String tmp = "";
		for (int i = 0; i < his.length; i++) {
			tmp += his[i];
			if (i != his.length - 1)
				tmp += "|";
		}
		return tmp;
	}

	private void prepScreen() throws JSONException, IOException {
		// titleLabel.setPadding(4, 0, 3, 4);
		titleLabel.setFont(titleLabel.getFont().derive(Font.PLAIN,
				titleLabel.getFont().getHeight() + 2));
		super.setTitle(titleLabel);

		s = (JSONObject) songs.get(0);

		s_pic = s.getString("picture");
		fetchImage(s_pic);

		bitField.setBitmap(bitmap.getBitmap());

		s_artist = s.getString("artist");
		s_title = s.getString("title");
		artistField.setText(s_title + "-" + s_artist);

		s_id = s.getString("sid");
		s_url = s.getString("url");
		playMp3(s_url);
		// processMenuItem();
	}

	private void caclSacle() {
		int hi = Display.getHeight();
		int ihi = bitmap.getHeight();
		System.out.println("hi:" + hi + ",ihi:" + ihi);
		System.out.println("ihi > .6 * hi:" + (ihi > .6 * hi));
		System.out.println("(int)(ihi / (hi * 600.0d) * 1000):"
				+ ((int) (ihi / (hi * 0.5d) * 1000 * 10)));
		int scale = 0;
		// if (ihi > .6 * hi) {
		scale = Fixed32.tenThouToFP((int) (ihi / (hi * 0.5d) * 1000 * 10));
		bitmap = bitmap.scaleImage32(scale/* Fixed32.QUARTER * 3 */, scale/*
																		 * Fixed32.
																		 * QUARTER
																		 * * 3
																		 */);
		// }
	}

	private void processMenuItem() {
		addMenuItem(next);
		addMenuItem(rate);
		addMenuItem(delete);
		addMenuItem(MenuItem.separator(delete.getOrdinal()));
		addMenuItem(_switchChannel);
		addMenuItem(MenuItem.separator(_switchChannel.getOrdinal()));
		addMenuItem(clearLogin);
		addMenuItem(MenuItem.separator(clearLogin.getOrdinal()));
		addMenuItem(setAutoClose);
		addMenuItem(about);
	}

	private boolean _retrieveSongsSusccess = false;

	private void playMp3(String url) {
		// Create and run the player's thread
		_playerThread = new PlayerThread(url);
		_playerThread.start();
	}

	private void fetchImage(String sPic) throws IOException {
		InputStream iStream = null;
		HttpConnection httpConnection = null;
		DataInputStream dis = null;
		try {
			System.out.println("picture:" + sPic);
			httpConnection = (HttpConnection) Connector.open(
					sPic + Radio.getConnectType(), Connector.READ_WRITE);
			httpConnection.setRequestMethod(HttpConnection.GET);
			int responseCode = httpConnection.getResponseCode();
			if (responseCode == HttpConnection.HTTP_OK) {

				int len = (int) httpConnection.getLength();
				byte[] buffer = new byte[len];
				dis = new DataInputStream(httpConnection.openInputStream());
				dis.readFully(buffer);

				bitmap = EncodedImage.createEncodedImage(buffer, 0, len);
				caclSacle();
			}
		} catch (IOException e) {
			System.out.println("fetching images:" + e.getClass() + ":"
					+ e.getMessage());
			Radio.errorDialog(SongPlayScreen._resources
					.getString(RadioResource.IO_ERROR));
		} finally {
			if (dis != null) {
				dis.close();
				dis = null;
			}
			if (httpConnection != null) {
				httpConnection.close();
				httpConnection = null;
			}
			if (iStream != null) {
				iStream.close();
				iStream = null;
			}
		}
	}

	private void prepData() {
		wrapURL();
		getSongData();

	}

	private void getSongData() {
		System.out.println("url before:" + _url);
		try {
			_httpConnection = (HttpConnection) Connector.open(_url
					+ Radio.getConnectType());
			_httpConnection
					.setRequestProperty(
							"User-Agent",
							"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8");
			_httpConnection.setRequestProperty("Cookie", LoginUtil.COO);
			System.out.println("length:" + _httpConnection.getLength());
			System.out.println("response code:"
					+ _httpConnection.getResponseCode());
			if (_httpConnection.getResponseCode() == HttpConnection.HTTP_OK) {
				String response = _httpConnection.getResponseMessage();
				System.out.println("response message:" + response);
				is = _httpConnection.openInputStream();

				// Get the length and process the data
				int len = (int) _httpConnection.getLength();
				if (len > 0) {
					int actual = 0;
					int bytesread = 0;
					byte[] data = new byte[len];
					while ((bytesread != len) && (actual != -1)) {
						actual = is.read(data, bytesread, len - bytesread);
						bytesread += actual;
					}
					String responText = new String(data, "utf-8");
					System.out.println("responText:" + responText);
					parseSongData(responText);
					_retrieveSongsSusccess = true;
					System.out.println("_changeChannel before:"
							+ _changeChannel);
					System.out.println("s_idx:" + s_idx);
					System.out.println("amount:" + amount);
					if (s_idx >= amount - 1)
						_changeChannel = true;
					System.out
							.println("_changeChannel after:" + _changeChannel);
				} else {
					System.out.println("len 's not exceed 0");
				}
			}
		} catch (IOException e) {
			System.out.println("Retrieving songs' list popped out error:"
					+ e.getMessage());
			Radio.errorDialog(SongPlayScreen._resources
					.getString(RadioResource.IO_ERROR));
		} finally {
			try {
				if (is != null) {
					is.close();
					is = null;
				}
				if (_httpConnection != null) {
					_httpConnection.close();
					_httpConnection = null;
				}
			} catch (IOException e) {
				System.out
						.println("Cleaning resources of Retrieving songs' list popped out error:"
								+ e.getMessage());
			}
		}
	}

	private void parseSongData(String response) {
		JSONTokener tokener = new JSONTokener(response);
		if (tokener.more()) {
			try {
				JSONObject object = (JSONObject) tokener.nextValue();
				System.out.println("object:" + object);
				songs = (JSONArray) object.get("song");
				amount = songs.length();
			} catch (JSONException e) {
				Radio.errorDialog(e.getMessage());
			}
		}
	}

	/**
	 * Called when the application exits, ensures that all attributes are
	 * destroyed correctly.
	 */
	public void close() {
		try {
			// Destroy the Player and streams
			// _source.delIncompleted();
			destroy();
			// LoginUtil.deleteDB();
			LoginUtil.updateChannel(channel);
		} catch (Exception e) {
			Radio.errorDialog("close() threw " + e.getMessage());
		} finally {
			System.exit(0);
			super.close();
		}
	}

	/**
	 * Prevent the save dialog from being displayed
	 * 
	 * @see net.rim.device.api.ui.container.MainScreen#onSavePrompt()
	 */
	protected boolean onSavePrompt() {
		return true;
	}

	/**
	 * Destroy the Player and streams
	 * 
	 * @throws MediaException
	 * @throws IOException
	 * 
	 * @throws Exception
	 *             Thrown if the media player could not be closed or if the
	 *             connection stream could not be closed
	 */
	private void destroy() throws MediaException, IOException {
		// Destroy the player.
		if (_player != null) {
			_player.stop();
			_player.close();
			_player = null;
		}

		// Destroy the stream.
		if (_source != null) {
			_source.stop();
			_source.disconnect();
			_source = null;
		}
	}

	public void playNext() throws JSONException, IOException {

		System.out.println("s_idx:" + s_idx);
		System.out.println("amount:" + amount);
		if (s_idx >= amount - 1) {
			int i = 0;
			System.out.println("_changeChannel:" + _changeChannel);
			while (!_changeChannel) {
				prepData();
				System.out.println("_changeChannel:" + _changeChannel);
				System.out.println("i:" + i);
				i++;
				if (i == 5 || _changeChannel) {
					break;
				}
			}
			_changeChannel = false;
			amount = songs.length();
			s_idx = rand.nextInt(amount - 1);
			System.out.println("s_idx:" + s_idx);
			System.out.println("amount:" + amount);
		} else {
			s_idx++;
		}

		s = (JSONObject) songs.get(s_idx);
		s_url = s.getString("url");
		s_pic = s.getString("picture");
		fetchImage(s_pic);

		s_artist = s.getString("artist");

		s_title = s.getString("title");

		// updateLayout();
		s_id = s.getString("sid");
		// s_url = s.getString("url");
		UiApplication.getUiApplication().invokeLater(new Runnable() {
			public void run() {
				artistField.setText(s_title + "-" + s_artist);
				/*
				 * bitmap = (JPEGEncodedImage) bitmap.scaleImage32(
				 * Fixed32.QUARTER * 3, Fixed32.QUARTER * 3);
				 */
				bitField.setImage(bitmap);
				updateLayout();
				playMp3(s_url);
			}
		});
	}

	private void songSkiped() throws IOException {
		processEndStatus("s");
	}

	private void processEndStatus(String type) {
		String urlEndStatus = _resources.getString(RadioResource.URL_BASE)
				+ "type=" + type + "&sid=" + s_id + "&uid=" + LoginUtil.UID
				+ "&channel=" + channel;
		System.out.println("before Loading:" + urlEndStatus);
		try {
			_httpConnection = (HttpConnection) Connector.open(urlEndStatus
					+ Radio.getConnectType());
			_httpConnection
					.setRequestProperty(
							"User-Agent",
							"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8");
			_httpConnection.setRequestProperty("Cookie", LoginUtil.COO);
			System.out.println("length:" + _httpConnection.getLength());
			if (_httpConnection.getResponseCode() == HttpConnection.HTTP_OK) {
				String response = _httpConnection.getResponseMessage();
				System.out.println("response message:" + response);
				is = _httpConnection.openInputStream();

				int len = (int) _httpConnection.getLength();

				if (len > 0) {
					int actual = 0;
					int bytesread = 0;
					byte[] data = new byte[len];
					while ((bytesread != len) && (actual != -1)) {
						actual = is.read(data, bytesread, len - bytesread);
						bytesread += actual;
					}
					String s = new String(data);
					System.out.println("end status sending result :" + s);
				}
			}

		} catch (IOException e) {
			System.out.println("in processEndStatust:e:" + e.getClass() + ":"
					+ e.getMessage());
			Radio.errorDialog(SongPlayScreen._resources
					.getString(RadioResource.IO_ERROR));

		} finally {
			if (type.equals("r"))
				return;
			try {
				if (is != null) {
					is.close();
					is = null;
				}
				if (_httpConnection != null) {
					_httpConnection.close();
					_httpConnection = null;
				}
				destroy();
				processHistory(type);
				playNext();
			} catch (IOException e) {
				System.out.println("cleaning reses of in processEndStatust:e:"
						+ e.getClass() + ":" + e.getMessage());
				Radio.errorDialog(SongPlayScreen._resources
						.getString(RadioResource.IO_ERROR));
			} catch (MediaException e) {
				System.out.println("in processEndStatust:e:" + e.getClass()
						+ ":" + e.getMessage());
				Radio.errorDialog("in processEndStatust:e:" + e.getClass()
						+ ":" + e.getMessage());
			} catch (JSONException e) {
				System.out.println("in processEndStatust:e:" + e.getClass()
						+ ":" + e.getMessage());
				Radio.errorDialog("in processEndStatust:e:" + e.getClass()
						+ ":" + e.getMessage());
			}
		}
	}

	private void processHistory(String type) {
		for (int i = 0; i < _history.length - 1; i++) {
			_history[i] = _history[i + 1];
		}
		_history[_history.length - 1] = s_id + ":" + type;
	}

	private void regularEnd() throws IOException {
		processEndStatus("e");
	}

	public PlayerListener playerListener = new PlayerListener() {

		public void playerUpdate(Player player, String event, Object eventData) {
			System.out.println("EVENT OF PLAYER:" + event);
			if (event.equals(PlayerListener.END_OF_MEDIA)) {
				try {
					regularEnd();
				} catch (IOException e) {
					System.out.println("end of media:" + e);
					System.out.println("end of media:" + e.getMessage());
					Radio.errorDialog(SongPlayScreen._resources
							.getString(RadioResource.IO_ERROR));
				}
				_timeStop = true;
			} else if (event.equals("com.rim.timeUpdate")) {
				/*
				 * synchronized (UiApplication.getEventLock()) {
				 * f_time.setText(formatTime()); updateLayout(); }
				 */
			}
		}

	};

	private String formatTime() {
		if (_player == null || _player.getState() == Player.CLOSED)
			return "00:00";
		int sec = (int) (_player.getMediaTime() / (1000 * 1000));
		int min = sec / 60;
		sec = sec % 60;
		String s_sec = String.valueOf(sec);
		String s_min = String.valueOf(min);
		if (sec < 10)
			s_sec = "0" + s_sec;
		if (min < 10)
			s_min = "0" + s_min;
		return s_min + ":" + s_sec;
	}

	protected boolean navigationClick(int status, int time) {
		return false;
	}

	/*
	 * protected boolean keyControl(char c, int status, int time) { if (c ==
	 * Characters.CONTROL_VOLUME_UP) { vc.setLevel(vc.getLevel() + 10); _volume
	 * = vc.getLevel(); } else if (c == Characters.CONTROL_VOLUME_DOWN) {
	 * vc.setLevel(vc.getLevel() - 10); _volume = vc.getLevel(); }
	 * 
	 * return super.keyControl(c, status, time); }
	 */

	protected boolean keyChar(char key, int status, int time) {
		// TODO Auto-generated method stub
		if (key == Characters.LATIN_SMALL_LETTER_N) {
			channelSwitch(100);
		} else if (key == Characters.LATIN_SMALL_LETTER_X) {
			close();
		} else if (key == Characters.LATIN_SMALL_LETTER_C) {
			Radio theApp = (Radio) getApplication();
			theApp.pushScreen(new ChannelScreen((SongPlayScreen) theApp
					.getActiveScreen()));
		}
		System.out.println("key:" + key);
		return super.keyChar(key, status, time);
	}

	/*protected boolean keyDown(int keycode, int time) { // TODO Auto-generated
		int code = Keypad.key(keycode);
		VolumeControl v = (VolumeControl) _player.getControl("VolumeControl");
		switch (code) {
		case 273:
			if (!v.isMuted())
				v.setMute(true);
			else
				v.setMute(false);
			break;
		case 4096:
			v.setLevel(v.getLevel() + 10);
			_volume = vc.getLevel();
			break;
		case 4097:
			v.setLevel(v.getLevel() - 10);
			_volume = vc.getLevel();
			break;
		}
		System.out.println("code:" + code);
		return super.keyDown(keycode, time);
	}*/

	private class PlayerThread extends Thread {
		private String url;

		public PlayerThread(String url) {
			this.url = url;
		}

		/**
		 * Create and start the player
		 * 
		 * @see java.lang.Runnable#run()
		 */
		public void run() {
			try {

				_source = new LimitedRateStreamingSource(url);

				// Set the attributes of the stream
				_source.setContentType("audio/mpeg");
				_source.setStartBuffer(200000);
				_source.setReadLimit(32000);
				_source.setResumeBytes(128000);
				_source.setPauseBytes(64000);
				_source.start();

				_player = Manager.createPlayer(_source);

				_player.addPlayerListener(playerListener);
				_player.prefetch();
				_player.realize();
				
				
				vc = (VolumeControl) _player.getControl("VolumeControl");
				// _volume = Audio.getVolume();
				// System.out.println("_volume:" + _volume);
				vc.setLevel(_volume);

				_player.start();
				_timeStop = false;
				Thread t = new Thread(new Runnable() {
					public void run() {
						for (;;) {
							if (_timeStop) {
								break;
							}
							synchronized (UiApplication.getEventLock()) {
								f_time.setText(formatTime());
								updateLayout();
							}
							try {
								Thread.sleep(rand.nextInt(1000));
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
					}

				});
				t.start();
			} catch (MediaException e) {
				System.out.println("in play thread:" + e.getClass() + ":"
						+ e.getMessage());
			} catch (IOException e) {
				System.out.println("in play thread:" + e.getClass() + ":"
						+ e.getMessage());
			}
		}
	}

	private class MyMenuItem extends MenuItem {
		private int c = 0;

		public MyMenuItem(ResourceBundle bundle, int id, int ordinal,
				int priority, int c) {
			super(bundle, id, ordinal, priority);
			this.c = c;
		}

		public void run() {
			Radio theApp = (Radio) getApplication();

			theApp.pushScreen(new ChannelScreen((SongPlayScreen) theApp
					.getActiveScreen()));
		}
	}

	public void channelSwitch(int c) {
		if (c != 100) {
			channel = c;
			s_idx = 100;
			String title = "";
			switch (channel) {
			case Channel.PERSONAL:
				title = _resources.getString(RadioResource.PERSONAL);
				break;
			case Channel.BEATLES_CHINESE:
				title = _resources.getString(RadioResource.BEATLES_CHINESE);
				break;
			case Channel.BALLAD:
				title = _resources.getString(RadioResource.BALLAD);
				break;
			case Channel.CANTONESE:
				title = _resources.getString(RadioResource.CANTONESE);
				break;
			case Channel.EUROPEAN:
				title = _resources.getString(RadioResource.EUROPEAN);
				break;
			case Channel.LIGHT_MUSIC:
				title = _resources.getString(RadioResource.LIGHT_MUSIC);
				break;
			case Channel.ROCK:
				title = _resources.getString(RadioResource.ROCK);
				break;
			case Channel.SEVENTIES:
				title = _resources.getString(RadioResource.SEVENTIES);
				break;
			case Channel.EIGHTIES:
				title = _resources.getString(RadioResource.EIGHTIES);
				break;
			case Channel.NINETIES:
				title = _resources.getString(RadioResource.NINETIES);
				break;
			case Channel.MOVIE_ORIGINAL:
				title = _resources.getString(RadioResource.MOVIE_ORIGINAL);
				break;
			case Channel.JAZZ:
				title = _resources.getString(RadioResource.JAZZ);
				break;
			case Channel.ELECTRONIC:
				title = _resources.getString(RadioResource.ELECTRONIC);
				break;
			case Channel.RAP:
				title = _resources.getString(RadioResource.RAP);
				break;
			case Channel.RB:
				title = _resources.getString(RadioResource.RB);
				break;
			case Channel.JAPANESE:
				title = _resources.getString(RadioResource.JAPANESE);
				break;
			case Channel.KOREAN:
				title = _resources.getString(RadioResource.KOREAN);
				break;
			case Channel.PUMA:
				title = _resources.getString(RadioResource.PUMA);
				break;
			case Channel.GIRLS:
				title = _resources.getString(RadioResource.GIRLS);
				break;
			case Channel.OMP:
				title = _resources.getString(RadioResource.OMP);
				break;
			case Channel.FRENCH:
				title = _resources.getString(RadioResource.FRENCH);
				break;
			case Channel.GEGE:
				title = _resources.getString(RadioResource.GEGE);
				break;
			}
			synchronized (UiApplication.getEventLock()) {
				titleLabel.setText(title, 0, title.length());
				setTitle(titleLabel);
				updateLayout();
			}
		}
		new Thread(new Runnable() {
			public void run() {
				try {
					songSkiped();
				} catch (IOException e) {
					System.out.println("menuitem next:" + e);
					System.out.println("menuitem next:" + e.getMessage());
					Radio.errorDialog(SongPlayScreen._resources
							.getString(RadioResource.IO_ERROR));
				}
			}
		}).start();
	}
}
